package com.rizzo.infrastructure.redis.key;

import com.rizzo.infrastructure.domain.KeyType;

/**
 * Builder DSL for creating {@link com.rizzo.infrastructure.redis.key.RedisKey}s
 */
public class RedisKeyBuilder {

    private RedisKey redisKey;

    public RedisKeyBuilder() {
    }

    public RedisKeyBuilder(RedisKey redisKey) {
        this.redisKey = redisKey;
    }

    public RedisKeyBuilder key(String application) {
        if (!application.contains(RedisKey.REDIS_KEY_DELIMITER)) {
            this.redisKey = new RedisKey(application);
        } else {
            throw new IllegalArgumentException("Application cannot contain char: " + RedisKey.REDIS_KEY_DELIMITER);
        }
        return this;
    }

    public RedisKeyBuilder instanceName(String instanceName) {
        if (!instanceName.contains(RedisKey.REDIS_KEY_DELIMITER)) {
            this.redisKey.setInstanceName(instanceName);
        } else {
            throw new IllegalArgumentException("InstanceName cannot contain char: " + RedisKey.REDIS_KEY_DELIMITER);
        }
        return this;
    }

    public RedisKeyBuilder instanceIndex(String instanceIndex) {
        if (!instanceIndex.contains(RedisKey.REDIS_KEY_DELIMITER)) {
            this.redisKey.setInstanceIndex(instanceIndex);
        } else {
            throw new IllegalArgumentException("InstanceIndex cannot contain char: " + RedisKey.REDIS_KEY_DELIMITER);
        }
        return this;
    }

    public RedisKeyBuilder type(KeyType type) {
        if (type != null) {
            this.redisKey.setType(type);
        } else {
            throw new IllegalArgumentException("Type cannot be null");
        }
        return this;
    }

    public RedisKeyBuilder category(String category) {
        if (!category.contains(RedisKey.REDIS_KEY_DELIMITER)) {
            this.redisKey.setCategory(category);
        } else {
            throw new IllegalArgumentException("Category cannot contain char: " + RedisKey.REDIS_KEY_DELIMITER);
        }
        return this;
    }

    /**
     * CAUTION: You can call this method only twice, after that it will throw an {@link IllegalArgumentException}.
     */
    public RedisKeyBuilder data(String data) {
        if (!data.contains(RedisKey.REDIS_KEY_DELIMITER)) {
            this.redisKey.addData(data);
        } else {
            throw new IllegalArgumentException("Data cannot contain char: " + RedisKey.REDIS_KEY_DELIMITER);
        }
        return this;
    }

    public RedisKey build() {
        if (this.redisKey.isValid()) {
            return this.redisKey;
        } else {
            throw new IllegalStateException("RedisKey is not valid!");
        }
    }
}
